import 'package:flutter/material.dart';
import 'package:json_annotation/json_annotation.dart';
import 'dart:convert';
import 'dart:developer';

part 'common_entity.g.dart';

void tryCatch(Function? f) {
  try {
    f?.call();
  } catch (e, stack) {
    log('$e');
    log('$stack');
  }
}

class FFConvert {
  FFConvert._();

  static T? Function<T extends Object?>(dynamic value) convert =
      <T>(dynamic value) {
    if (value == null) {
      return null;
    }
    return json.decode(value.toString()) as T?;
  };
}

T? asT<T extends Object?>(dynamic value, [T? defaultValue]) {
  if (value is T) {
    return value;
  }
  try {
    if (value != null) {
      final String valueS = value.toString();
      if ('' is T) {
        return valueS as T;
      } else if (0 is T) {
        return int.parse(valueS) as T;
      } else if (0.0 is T) {
        return double.parse(valueS) as T;
      } else if (false is T) {
        if (valueS == '0' || valueS == '1') {
          return (valueS == '1') as T;
        }
        return (valueS == 'true') as T;
      } else {
        return FFConvert.convert<T>(value);
      }
    }
  } catch (e, stackTrace) {
    log('asT<$T>', error: e, stackTrace: stackTrace);
    return defaultValue;
  }

  return defaultValue;
}

class ProvinceRspModel {
  ProvinceRspModel({
    required this.title,
    required this.provinceId,
    required this.cities,
  });

  /// 省份级别
  factory ProvinceRspModel.all() {
    return ProvinceRspModel(title: "全国", provinceId: -1, cities: []);
  }

  factory ProvinceRspModel.fromJson(Map<String, dynamic> json) {
    final List<CitiesRspEntity>? cities =
        json['cities'] is List ? <CitiesRspEntity>[] : null;
    if (cities != null) {
      for (final dynamic item in json['cities']!) {
        if (item != null) {
          tryCatch(() {
            cities.add(
                CitiesRspEntity.fromJson(asT<Map<String, dynamic>>(item)!));
          });
        }
      }
    }
    return ProvinceRspModel(
      title: asT<String>(json['title'])!,
      provinceId: asT<int>(json['province_id'])!,
      cities: cities!,
    );
  }

  String title;
  int provinceId;
  List<CitiesRspEntity> cities;

  @override
  String toString() {
    return jsonEncode(this);
  }

  Map<String, dynamic> toJson() => <String, dynamic>{
        'title': title,
        'province_id': provinceId,
        'cities': cities,
      };
}

class CitiesRspEntity {
  CitiesRspEntity({
    required this.cityId,
    required this.cityName,
    required this.amapCode,
  });

  factory CitiesRspEntity.no() =>
      CitiesRspEntity(cityId: 1, amapCode: '', cityName: '');

  /// 全国
  factory CitiesRspEntity.full() =>
      CitiesRspEntity(cityId: 0, amapCode: '', cityName: '全国');

  factory CitiesRspEntity.fromJson(Map<String, dynamic> json) =>
      CitiesRspEntity(
        cityId: asT<int>(json['city_id'])!,
        cityName: asT<String>(json['city_name'])!,
        amapCode: asT<String>(json['amap_code'])!,
      );

  int cityId;
  String cityName;
  String amapCode;

  @override
  String toString() {
    return jsonEncode(this);
  }

  Map<String, dynamic> toJson() => <String, dynamic>{
        'city_id': cityId,
        'city_name': cityName,
        'amap_code': amapCode,
      };
}

class PriceListRspEntity {
  PriceListRspEntity({
    this.priceList,
    this.vipIntroduceOuter,
    this.vipIntroduceInner,
    this.vipIntroduce,
    this.index,
    this.imgUrl,
    this.wekakaSurface,
    this.wekakaSurfaceMsg,
    this.failNote,
    this.depositNum,
  });

  factory PriceListRspEntity.fromJson(Map<String, dynamic> json) {
    final List<PriceList>? priceList =
        json['price_list'] is List ? <PriceList>[] : null;
    if (priceList != null) {
      for (final dynamic item in json['price_list']!) {
        if (item != null) {
          tryCatch(() {
            priceList.add(PriceList.fromJson(asT<Map<String, dynamic>>(item)!));
          });
        }
      }
    }
    final List<VipIntroduce>? vipIntroduceOuter =
        json['vip_introduce_outer'] is List ? <VipIntroduce>[] : null;
    if (vipIntroduceOuter != null) {
      for (final dynamic item in json['vip_introduce_outer']!) {
        if (item != null) {
          tryCatch(() {
            vipIntroduceOuter
                .add(VipIntroduce.fromJson(asT<Map<String, dynamic>>(item)!));
          });
        }
      }
    }
    final List<VipIntroduce>? vipIntroduceInner =
        json['vip_introduce_inner'] is List ? <VipIntroduce>[] : null;
    if (vipIntroduceInner != null) {
      for (final dynamic item in json['vip_introduce_inner']!) {
        if (item != null) {
          tryCatch(() {
            vipIntroduceInner
                .add(VipIntroduce.fromJson(asT<Map<String, dynamic>>(item)!));
          });
        }
      }
    }

    final List<List<String>>? vipIntroduce =
        json['vip_introduce'] is List ? <List<String>>[] : null;
    if (vipIntroduce != null) {
      for (final dynamic item0 in asT<List<dynamic>>(json['vip_introduce'])!) {
        if (item0 != null) {
          final List<String> items1 = <String>[];
          for (final dynamic item1 in asT<List<dynamic>>(item0)!) {
            if (item1 != null) {
              tryCatch(() {
                items1.add(asT<String>(item1)!);
              });
            }
          }
          vipIntroduce.add(items1);
        }
      }
    }
    return PriceListRspEntity(
      priceList: priceList,
      vipIntroduceOuter: vipIntroduceOuter,
      vipIntroduceInner: vipIntroduceInner,
      vipIntroduce: vipIntroduce,
      index: asT<int?>(json['index']),
      imgUrl: asT<String?>(json['img_url']),
      wekakaSurface: asT<String?>(json['wx_surface']),
      wekakaSurfaceMsg: asT<String?>(json['wx_surface_msg']),
      failNote: asT<String?>(json['fail_note']),
      depositNum: asT<String?>(json['deposit_num']),
    );
  }

  List<PriceList>? priceList;
  List<VipIntroduce>? vipIntroduceOuter;
  List<VipIntroduce>? vipIntroduceInner;

  List<List<String>>? vipIntroduce;
  int? index;
  String? imgUrl;
  String? wekakaSurface;
  String? wekakaSurfaceMsg;
  String? failNote;
  String? depositNum;

  @override
  String toString() {
    return jsonEncode(this);
  }

  Map<String, dynamic> toJson() => <String, dynamic>{
        'price_list': priceList,
        'vip_introduce_outer': vipIntroduceOuter,
        'vip_introduce_inner': vipIntroduceInner,
        'vip_introduce': vipIntroduce,
        'index': index,
        'img_url': imgUrl,
        'wx_surface': wekakaSurface,
        'wx_surface_msg': wekakaSurfaceMsg,
        'fail_note': failNote,
        'deposit_num': depositNum,
      };
}

class PriceList {
  PriceList({
    this.type,
    this.statementFront,
    this.statementRear,
    this.priceCn,
    this.priceEachMCn,
    this.specialty,
    this.price,
  });

  factory PriceList.fromJson(Map<String, dynamic> json) => PriceList(
        type: asT<int?>(json['type']),
        statementFront: asT<String?>(json['statement_front']),
        statementRear: asT<String?>(json['statement_rear']),
        priceCn: asT<String?>(json['price_cn']),
        priceEachMCn: asT<String?>(json['price_each_m_cn']),
        specialty: asT<String?>(json['specialty']),
        price: asT<int?>(json['price']),
      );

  int? type;
  String? statementFront;
  String? statementRear;
  String? priceCn;
  String? priceEachMCn;
  String? specialty;
  int? price;

  @override
  String toString() {
    return jsonEncode(this);
  }

  Map<String, dynamic> toJson() => <String, dynamic>{
        'type': type,
        'statement_front': statementFront,
        'statement_rear': statementRear,
        'price_cn': priceCn,
        'price_each_m_cn': priceEachMCn,
        'specialty': specialty,
        'price': price,
      };
}

class VipIntroduce {
  VipIntroduce({
    this.imgUrl,
    this.content,
  });

  factory VipIntroduce.fromJson(Map<String, dynamic> json) => VipIntroduce(
        imgUrl: asT<String?>(json['img_url']),
        content: asT<String?>(json['content']),
      );

  String? imgUrl;
  String? content;

  @override
  String toString() {
    return jsonEncode(this);
  }

  Map<String, dynamic> toJson() => <String, dynamic>{
        'img_url': imgUrl,
        'content': content,
      };
}

class VersionRspEntity {
  VersionRspEntity({
    this.androidUrl,
    this.force,
    this.iosUrl,
    this.version,
    this.content,
  });

  factory VersionRspEntity.fromJson(Map<String, dynamic> json) =>
      VersionRspEntity(
        androidUrl: asT<String?>(json['androidUrl']),
        force: asT<bool?>(json['force']),
        iosUrl: asT<String?>(json['iosUrl']),
        version: asT<String?>(json['version']),
        content: asT<String?>(json['content']),
      );

  String? androidUrl;
  bool? force;
  String? iosUrl;
  String? version;
  String? content;

  @override
  String toString() {
    return jsonEncode(this);
  }

  Map<String, dynamic> toJson() => <String, dynamic>{
        'androidUrl': androidUrl,
        'force': force,
        'iosUrl': iosUrl,
        'version': version,
        'content': content,
      };

  VersionRspEntity copy() {
    return VersionRspEntity(
      androidUrl: androidUrl,
      force: force,
      iosUrl: iosUrl,
      version: version,
      content: content,
    );
  }
}

class PayData {
  PayData({
    this.payChannel,
    this.payIndex,
    this.payByH5,
  });

  factory PayData.fromJson(Map<String, dynamic> json) {
    final List<PayChannel>? payChannel =
        json['pay_channel'] is List ? <PayChannel>[] : null;
    if (payChannel != null) {
      for (final dynamic item in json['pay_channel']!) {
        if (item != null) {
          tryCatch(() {
            payChannel
                .add(PayChannel.fromJson(asT<Map<String, dynamic>>(item)!));
          });
        }
      }
    }
    return PayData(
      payChannel: payChannel,
      payIndex: asT<int?>(json['pay_index']),
      payByH5: asT<int?>(json['pay_by_h5']),
    );
  }

  List<PayChannel>? payChannel;
  int? payIndex;
  int? payByH5;

  @override
  String toString() {
    return jsonEncode(this);
  }

  Map<String, dynamic> toJson() => <String, dynamic>{
        'pay_channel': payChannel,
        'pay_index': payIndex,
        'pay_by_h5': payByH5,
      };

  PayData copy() {
    return PayData(
      payChannel: payChannel?.map((PayChannel e) => e.copy()).toList(),
      payIndex: payIndex,
      payByH5: payByH5,
    );
  }
}

class PayChannel {
  PayChannel({
    this.channel,
  });

  factory PayChannel.fromJson(Map<String, dynamic> json) => PayChannel(
        channel: asT<int?>(json['channel']),
      );

  int? channel;

  @override
  String toString() {
    return jsonEncode(this);
  }

  Map<String, dynamic> toJson() => <String, dynamic>{
        'channel': channel,
      };

  PayChannel copy() {
    return PayChannel(
      channel: channel,
    );
  }
}

class GetServiceDataEntity {
  GetServiceDataEntity({
    this.questions,
    this.serviceId,
    this.serverIcon,
    this.serverNickname,
  });

  factory GetServiceDataEntity.fromJson(Map<String, dynamic> json) {
    final List<Questions>? questions =
        json['questions'] is List ? <Questions>[] : null;
    if (questions != null) {
      for (final dynamic item in json['questions']!) {
        if (item != null) {
          tryCatch(() {
            questions.add(Questions.fromJson(asT<Map<String, dynamic>>(item)!));
          });
        }
      }
    }
    return GetServiceDataEntity(
      questions: questions,
      serviceId: asT<String?>(json['service_id']),
      serverIcon: asT<String?>(json['server_icon']),
      serverNickname: asT<String?>(json['server_nickname']),
    );
  }

  List<Questions>? questions;
  String? serviceId;
  String? serverIcon;
  String? serverNickname;

  @override
  String toString() {
    return jsonEncode(this);
  }

  Map<String, dynamic> toJson() => <String, dynamic>{
        'questions': questions,
        'service_id': serviceId,
        'server_icon': serverIcon,
        'server_nickname': serverNickname,
      };
}

class Questions {
  Questions({
    this.question,
    this.answer,
  });

  factory Questions.fromJson(Map<String, dynamic> json) => Questions(
        question: asT<String?>(json['question']),
        answer: asT<String?>(json['answer']),
      );

  String? question;
  String? answer;

  @override
  String toString() {
    return jsonEncode(this);
  }

  Map<String, dynamic> toJson() => <String, dynamic>{
        'question': question,
        'answer': answer,
      };
}

@JsonSerializable()
class AreaCode {
  @JsonKey(name: 'english_name')
  final String englishName;
  @JsonKey(name: 'chinese_name')
  final String chineseName;
  @JsonKey(name: 'phone_code')
  final String phoneCode;

  AreaCode(this.englishName, this.chineseName, this.phoneCode);

  factory AreaCode.fromJson(Map<String, dynamic> json) =>
      _$AreaCodeFromJson(json);

  Map<String, dynamic> toJson() => _$AreaCodeToJson(this);
}
